/*
 * TowerBlueOne.java
 *
 * Created on 27 December 2007, 12:37
 *
 * Copyright (C) 2007-2008  Hylke van der Schaaf
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, in version 3 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
package hextd.tower;

import hextd.Constants;
import hextd.creep.HexTDCreep;
import hextd.util.Geometry;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.Area;
import java.awt.geom.CubicCurve2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.util.HashMap;
import java.util.Map;
import com.usoog.tdcore.exception.TileAlreadyHasTowerException;
import com.usoog.tdcore.exception.TileNotBuildableException;

/**
 *
 * @author hylke
 */
public class TowerBlueOne extends TowerBase {

	public static final Map<String, Long> price = new HashMap<String, Long>();

	static {
		price.put(Constants.RESOURCE_CREDIT, 500l);
	}
	public static int damage = 0;
	public static double range = 5f;
	public static String name = "Blue One";
	//
	private Constants.COLOR damageColor = Constants.COLOR.BLUE;
	private int coolDown = 0;
	private int coolDownMax = 79;
	private String[] newModes = {"Fastest"};
	//
	private Color transColor;
	//
	private HexTDCreep[] currentTargets = new HexTDCreep[0];
	private Point2D.Double tempTargetLocation = new Point2D.Double();

	/** Creates a new instance of TowerBlueOne */
	public TowerBlueOne() throws
			TileAlreadyHasTowerException,
			TileNotBuildableException {
		super(FactoryTower.type.blueOne, price, damage, range);
		lineColor = new Color(75, 75, 255);
		hexInfluence = 1;
		transColor = new Color(lineColor.getRed(), lineColor.getGreen(), lineColor.getBlue(), 75);
		modes = newModes;
	}

	@Override
	protected void makeButtons() {
		super.makeButtons();
		pts.setCanLock(false);
	}

	@Override
	public String getStatusString() {
		String retString = "";
		retString += "<h1>Blue Tower 1</h1>"
				+ "<p>"
				+ "<b>Level:</b> " + (1 + level) + "<br>\n"
				+ "<b>Slowdown:</b> " + TowerBlueOne.form.format(100.0 - 300.0 / (4 + level)) + "%<br>\n"
				+ "<b>Range:</b> " + rangeText + "<br>"
				+ "</p>\n";
		return retString;
	}

	@Override
	public String getDescription() {
		String retString = "";
		retString += "<h1>Blue Tower 1</h1>"
				+ "<p>"
				+ "Tower with four energy beams that overheat the targets engines, reducing it's top speed.<br>"
				+ "More hits make the effect last longer and upgrading the tower makes the effect stronger."
				+ "<br>It's effect is strong against blue enemies but very weak against yellow enemies."
				+ "</p>"
				+ "<p>"
				+ "<b>Price:</b> " + TowerBlueOne.price + "<br>"
				+ "<b>Damage:</b> none, slowdown instead<br>"
				+ "<b>Range:</b> " + TowerBlueOne.form.format(rangeCurrent) + "<br>"
				+ "<b>Refire rate:</b> 0.25/s"
				+ "</p>";
		return retString;
	}

	@Override
	public void runTick(int gameTime) {
		if (coolDown > 0) {
			coolDown--;
		} else {
			currentTargets = findEnemiesFastest(gameLocation.x, gameLocation.y, rangeCurrent, 4, false);
			if (currentTargets.length > 0) {
				HexTDCreep enemy;
				for (int i = 0; i < currentTargets.length; i++) {
					enemy = currentTargets[i];
					enemy.doDamage(getOwner(), 3000l / (4 + level), Constants.DamageType.power, damageColor);
				}

				coolDown = coolDownMax;
			}
		}
	}

	@Override
	protected void generateShapes() {

		int shapeCount = 3;
		int i;
		double[][] points = Geometry.createHexCoords(paintScale);
		double[][] points2 = Geometry.createHexCoords(paintScale * 0.2f);

		shapes = new Shape[shapeCount];
		i = 0;
		GeneralPath poly = new GeneralPath(GeneralPath.WIND_EVEN_ODD);
		poly.append(new CubicCurve2D.Double(points[0][0], points[0][1], points2[0][0], points2[0][1], points2[2][0], points2[2][1], points[2][0], points[2][1]), true);
		poly.append(new CubicCurve2D.Double(points[2][0], points[2][1], points2[2][0], points2[2][1], points2[4][0], points2[4][1], points[4][0], points[4][1]), true);
		poly.append(new CubicCurve2D.Double(points[4][0], points[4][1], points2[4][0], points2[4][1], points2[0][0], points2[0][1], points[0][0], points[0][1]), true);
		poly.append(new CubicCurve2D.Double(points[1][0], points[1][1], points2[1][0], points2[1][1], points2[3][0], points2[3][1], points[3][0], points[3][1]), false);
		poly.append(new CubicCurve2D.Double(points[3][0], points[3][1], points2[3][0], points2[3][1], points2[5][0], points2[5][1], points[5][0], points[5][1]), true);
		poly.append(new CubicCurve2D.Double(points[5][0], points[5][1], points2[5][0], points2[5][1], points2[1][0], points2[1][1], points[1][0], points[1][1]), true);
		poly.append(new Ellipse2D.Double(-0.6 * paintScale, -0.6 * paintScale, 1.2 * paintScale, 1.2 * paintScale), false);
		shapes[i++] = new Area(poly);
		shapes[i++] = shapes[0];
		shapes[i++] = new Ellipse2D.Double(-1.0 * strokeScale, -1.0 * strokeScale, 2.0 * strokeScale, 2.0 * strokeScale);

		i = 0;
		shapeAction = new int[shapeCount];
		shapeAction[i++] = 2;
		shapeAction[i++] = 1;
		shapeAction[i++] = 1;

		i = 0;
		shapeColor = new Color[shapeCount];
		shapeColor[i++] = transColor;
		shapeColor[i++] = lineColor;
		shapeColor[i++] = lineColor;

		i = 0;
		strokes = new Stroke[shapeCount];
		strokes[i++] = new BasicStroke(2.0f * strokeScale, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL);
		strokes[i++] = strokes[0];
		strokes[i++] = strokes[0];
	}

	@Override
	public void paintEffects(Graphics2D g2, int gameTime) {
		Stroke defaultStroke = g2.getStroke();

		if (currentTargets.length > 0 && coolDown > coolDownMax - 3) {
			g2.setColor(lineColor);
			for (int i = 0; i < currentTargets.length; i++) {
				currentTargets[i].getPaintLocation(tempTargetLocation);
				g2.draw(new Line2D.Double(paintLocation.x, paintLocation.y, tempTargetLocation.x, tempTargetLocation.y));
			}
		}

		g2.setStroke(defaultStroke);
	}
}
